home *** CD-ROM | disk | FTP | other *** search
- /*
- File: ODDocRef.cpp
-
- Contains: Implementation of ODDocRef.h
-
- This class is meant to replace the routines in DocUtils.cpp and
- provide a much more robust mechanism for opening OpenDoc files
- and displaying drafts.
-
- Owned by: Nick Pilch
-
- Copyright:
-
- Change History (most recent first):
-
- <5> 10/5/96 TJ 1392437 Fixed read/write permissions.
- <4> 10/5/96 NP Comments concerning changes to DocUtils.
- <3> 27.09.1996 NP 1386083: Removed some code.
- <2> 20.09.1996 NP 1386083: Rewrite document opening code.
- <1> 18.09.1996 NP first checked in
-
- To Do:
- */
-
- #ifndef _ODDOCREF_
- #include "ODDocRef.h"
- #endif
-
- #ifndef _PLFMFILE_
- #include "PlfmFile.h"
- #endif
-
- #ifndef _DOCUTILS_
- #include "DocUtils.h"
- #endif
-
- #ifndef _STORUTIL_
- #include "StorUtil.h"
- #endif
-
- #ifndef _TEMPOBJ_
- #include "TempObj.h"
- #endif
-
-
- #ifndef _DOCUTILP_
- #include "DocUtilP.h"
- #endif
-
-
- #ifndef SOM_ODSession_xh
- #include <ODSessn.xh>
- #endif
-
- #ifndef SOM_ODDraft_xh
- #include <Draft.xh>
- #endif
-
- #ifndef SOM_ODDocument_xh
- #include <Document.xh>
- #endif
-
- #ifndef SOM_ODObjectNameSpace_xh
- #include "ObjectNS.xh"
- #endif
-
- #ifndef SOM_ODNameSpaceManager_xh
- #include <NmSpcMg.xh>
- #endif
-
- #ifndef SOM_ODContainer_xh
- #include <ODCtr.xh>
- #endif
-
- #ifndef SOM_ODWindowState_xh
- #include <WinStat.xh>
- #endif
-
- #ifndef SOM_ODDispatcher_xh
- #include <Disptch.xh>
- #endif
-
- #ifndef SOM_ODLinkManager_xh
- #include <LinkMgr.xh>
- #endif
-
-
- #include <stdio.h>
-
-
-
- const ODISOStr kODRefNumDocument = "RefNumDocument";
- const ODISOStr kODDocumentTempDraft = "DocumentTempDraft";
-
-
-
-
- static ODFileRefNum DeduceRefNum(PlatformFile* file,
- ODULong prevRefNumCount,
- ODSShort* prevRefNums);
- static void CreateISOStrKeyFromULong(ODULong uLongKey, char str[9]);
-
-
- //------------------------------------------------------------------------------
- // ODOpenDocumentRef::ODOpenDocumentRef
- //------------------------------------------------------------------------------
-
- ODOpenDocumentRef::ODOpenDocumentRef(ODSession* session,
- PlatformFile* document,
- ODDraftPermissions permissions)
- {
- WASSERT(session != kODNULL);
- WASSERT(document != kODNULL);
-
- fSession = session;
- fFile = document;
- fPermissions = permissions;
-
- fContainer = kODNULL;
- fDocument = kODNULL;
- fRefNum = 0;
- fTempDraft = kODNULL;
- fNameSpaceManager = kODNULL;
- }
-
- //------------------------------------------------------------------------------
- // ODOpenDocumentRef::~ODOpenDocumentRef
- //------------------------------------------------------------------------------
-
- ODOpenDocumentRef::~ODOpenDocumentRef()
- {
- // PlatformFile::IsOpenDocDocument('xxxx','xxxx');
- }
-
- //------------------------------------------------------------------------------
- // DeduceRefNum
- //------------------------------------------------------------------------------
-
- static ODFileRefNum DeduceRefNum(PlatformFile* file,
- ODULong prevRefNumCount,
- ODSShort* prevRefNums)
- {
- ODFileRefNum retval = 0;
- ODULong newRefNumCount = 0;
- ODSShort* newRefNums = kODNULL;
-
- file->GetLocalPaths(kODDataFork, &newRefNumCount, &newRefNums);
-
- WASSERT(newRefNumCount == prevRefNumCount + 1);
-
- ODULong i = 0,j;
- ODBoolean found = kODFalse;
-
- while (i<newRefNumCount)
- {
- j = 0;
- while (j<prevRefNumCount && (found = (newRefNums[i] == prevRefNums[j]))==kODFalse)
- ++j;
- if (!found)
- break;
- ++i;
- }
-
- WASSERT(i<newRefNumCount);
-
- retval = newRefNums[i];
-
- if (newRefNums)
- ODDisposePtr((Ptr)newRefNums);
-
- return retval;
- }
-
- //------------------------------------------------------------------------------
- // ODOpenDocumentRef::Open
- //
- // acquires top draft
- // acquires top draft again and temp draft if it's a read/write document.
- //------------------------------------------------------------------------------
-
- ODDraft* ODOpenDocumentRef::Open(Environment* ev)
- {
- ODDraft* currentDraft = kODNULL;
- ODULong refNumCount, i;
- ODSShort* refNums = kODNULL;
- ODError error = kODNoError;
-
- ODVolatile(currentDraft);
- ODVolatile(refNums);
- ODVolatile(fTempDraft);
-
- fNameSpaceManager = fSession->GetNameSpaceManager(ev);
-
- TRY
- ODDocument* document = kODNULL;
-
- refNumCount = 0;
- fFile->GetLocalPaths(kODDataFork, &refNumCount, &refNums);
-
- // ACQUIRING ALREADY OPEN DRAFT BECAUSE WE HAVE TO RELEASE IT WHERE??????????
- // NP: I have yet to see this code executed. When does it?
- for ( i=0; i<refNumCount; ++i)
- {
- if ((document = ODGetOpenDocumentFromRefNum(ev, fSession, refNums[i])) != kODNULL)
- {
- WARN("This really happens!");
- currentDraft = ODGetTempDraftFromOpenDocument(ev, fSession, document);
- if (currentDraft)
- currentDraft->Acquire(ev);
- else
- currentDraft = document->AcquireDraft(ev,kODDPReadOnly,0,kODNULL,kODPosTop,kODFalse);
- if (refNums)
- ODDisposePtr(refNums);
- return currentDraft; // exit point
- }
- }
-
- // reusing currentDraft variable here
- currentDraft = this->AcquireCtrDocTopDraft(ev);
- // AcquireCtrDocTopDraft opens the file and adds a new refnum, so we
- // should be able to deduce it.
- fRefNum = DeduceRefNum(fFile, refNumCount, refNums);
-
- CATCH_ALL
- error = ErrorCode();
- if (currentDraft)
- ODFinalReleaseObject(ev, currentDraft);
- ODFinalReleaseObject(ev, fDocument);
- ODFinalReleaseObject(ev, fContainer);
- // We will reraise right below after freeing memory.
- ENDTRY
-
- // Make sure to free memory
- if (refNums)
- ODDisposePtr(refNums);
-
- // reraise here
- THROW_IF_ERROR(error);
-
- TRY
- // Create temp draft for doc with write permissions.
- if (HAS_WRITE_ACCESS(fPermissions) && !fFile->IsLocked())
- {
- // draft acquire
- currentDraft =
- fDocument->AcquireDraft(ev, fPermissions, 0, currentDraft,
- kODPosSame, kODTrue);
- // new refcount is still 1.
- currentDraft = fDocument->CreateDraft(ev, currentDraft, kODTrue);
- // former top draft now released and new draft has refCount of 1
- // draft acquire
- // Because "The caller is responsible for properly refcounting
- // the temp draft."
- // From DocUtils.h documentation of ODDocumentOpened.
- currentDraft->Acquire(ev);
- // top draft refcount now 2, will get released in
- // RealShell::OpenFile
- // set instance variable
- fTempDraft = currentDraft;
- }
-
- this->DocumentOpened(ev);
- CATCH_ALL
- if (fTempDraft)
- {
- // Need to call release twice. Don't use ODReleaseObject.
- fTempDraft->Release(ev);
- ODFinalReleaseObject(ev, fTempDraft);
- }
- else
- ODFinalReleaseObject(ev, currentDraft);
- ODFinalReleaseObject(ev, fDocument);
- ODFinalReleaseObject(ev, fContainer);
- RERAISE;
- ENDTRY
-
- // We don't have to worry about ODDocumentOpened anymore.
-
- // Want to release these here, because ODDocumentOpened will acquire
- // them!!!!! ODDocumentOpened wants to be balanced with
- // ODDocumentClosed. (These multiple-purpose utilities are called in other
- // contexts, so which it's important to preserve semantics.)
- // TempODContainer tempCont = fContainer; // container release
- // TempODDocument tempDoc = fDocument; // document release
-
- return currentDraft;
- }
-
- //------------------------------------------------------------------------------
- // ODOpenDocumentRef::OpenDraft
- //------------------------------------------------------------------------------
-
- void ODOpenDocumentRef::OpenDraft(Environment* ev, ODDraft* draft)
- {
- // Just calling the utility because there's no changes I want to make to
- // ODOpenDraft at
- // this time. I believe that the ODWindowState calls made in need to be
- // revved. They need to be able to completely clean up after themselves.
- // This includes closing all windows and releasing any parts that they
- // created.
- ODOpenDraft(ev, fSession, draft);
- }
- #if 0
- //------------------------------------------------------------------------------
- // ODOpenDocumentRef::Save
- //------------------------------------------------------------------------------
-
- void ODOpenDocumentRef::Save(Environment* ev)
- {
- }
-
- //------------------------------------------------------------------------------
- // ODOpenDocumentRef::Close
- //------------------------------------------------------------------------------
-
- void ODOpenDocumentRef::Close(Environment* ev)
- {
- }
-
- //------------------------------------------------------------------------------
- // ODOpenDocumentRef::GetDocument
- //------------------------------------------------------------------------------
-
- ODDocument* ODOpenDocumentRef::GetDocument()
- {
- return 0;
- }
-
- //------------------------------------------------------------------------------
- // ODOpenDocumentRef::GetTopDraft
- //------------------------------------------------------------------------------
-
- ODDraft* ODOpenDocumentRef::GetTopDraft()
- {
- return 0;
- }
- #endif /* 0 */
- //------------------------------------------------------------------------------
- // ODOpenDocumentRef::AcquireCtrDocTopDraft
- //
- // acuires container and document and draft returned
- //------------------------------------------------------------------------------
-
- ODDraft* ODOpenDocumentRef::AcquireCtrDocTopDraft(Environment* ev)
- {
- ODDraft* draft = kODNULL;
-
- TRY
- fContainer = AcquireFileContainer(ev, fSession, &(fFile->GetFileSpec()));
- fDocument = fContainer->AcquireDocument(ev, kODDefaultDocument);
- draft = fDocument->AcquireDraft(ev, kODDPReadOnly, 0, kODNULL, kODPosTop,
- kODFalse);
- CATCH_ALL
- if (fDocument)
- ODFinalReleaseObject(ev, fDocument);
- if (fContainer)
- ODFinalReleaseObject(ev, fContainer);
- RERAISE;
- ENDTRY
-
- return draft;
- }
-
- //------------------------------------------------------------------------------
- // CreateISOStrKeyFromULong
- //------------------------------------------------------------------------------
-
- static void CreateISOStrKeyFromULong(ODULong uLongKey, char str[9])
- {
- sprintf(str,"%.8lX",uLongKey);
- }
-
- //------------------------------------------------------------------------------
- // ODOpenDocumentRef::DocumentOpened
- //
- //
- //------------------------------------------------------------------------------
-
- void ODOpenDocumentRef::DocumentOpened(Environment* ev)
- {
- // document acquire
- // fDocument->Acquire(ev); // Balanced by Release in ODDocumentClosed.
- // container acquire
- // fDocument->GetContainer(ev)->Acquire(ev); // Balanced by Release in
- // ODDocumentClosed.
-
- this->AddToRefNumDocNS(ev);
-
- if (fTempDraft)
- {
- TRY
- this->AddToTempDraftNS(ev);
- CATCH_ALL
- this->RemoveFromRefNumDocNS(ev);
- RERAISE;
- ENDTRY
- }
- }
-
- //------------------------------------------------------------------------------
- // ODOpenDocumentRef::AddToRefNumDocNS
- //------------------------------------------------------------------------------
-
- void ODOpenDocumentRef::AddToRefNumDocNS(Environment* ev)
- {
- ODObjectNameSpace* nameSpace =
- (ODObjectNameSpace*)fNameSpaceManager->HasNameSpace( ev,
- kODRefNumDocument);
- if (!nameSpace)
- {
- nameSpace =
- (ODObjectNameSpace*)fNameSpaceManager->CreateNameSpace(
- ev, kODRefNumDocument, kODNULL, 5, kODNSDataTypeODObject);
- }
-
- {
- char key[9];
- CreateISOStrKeyFromULong((ODULong)fRefNum, key);
- #if ODDebug
- ODDocument* unusedDocument;
- if (nameSpace->GetEntry(ev, key, (ODObject**)&unusedDocument))
- WARN("refnum already in kODRefNumDocument namespace!");
- #endif
- nameSpace->Register(ev, key, fDocument);
- }
-
- }
-
- //------------------------------------------------------------------------------
- // ODOpenDocumentRef::RemoveFromRefNumDocNS
- //------------------------------------------------------------------------------
-
- void ODOpenDocumentRef::RemoveFromRefNumDocNS(Environment* ev)
- {
- ODObjectNameSpace* nameSpace =
- (ODObjectNameSpace*)fNameSpaceManager->HasNameSpace( ev,
- kODRefNumDocument);
- if (nameSpace)
- {
- char key[9];
- CreateISOStrKeyFromULong((ODULong)fRefNum, key);
- #if ODDebug
- ODDocument* unusedDocument;
- if (!nameSpace->GetEntry(ev, key, (ODObject**)&unusedDocument))
- WARN("refnum not in kODRefNumDocument namespace!");
- #endif
- nameSpace->Unregister(ev, key);
- }
- }
-
- //------------------------------------------------------------------------------
- // ODOpenDocumentRef::AddToTempDraftNS
- //------------------------------------------------------------------------------
-
- void ODOpenDocumentRef::AddToTempDraftNS(Environment* ev)
- {
- ODNameSpaceManager* fNameSpaceManager = fSession->GetNameSpaceManager(ev);
-
- ODObjectNameSpace* nameSpace =
- (ODObjectNameSpace*)fNameSpaceManager->HasNameSpace( ev,
- kODDocumentTempDraft);
- if (!nameSpace)
- {
- nameSpace =
- (ODObjectNameSpace*)fNameSpaceManager->CreateNameSpace(
- ev, kODDocumentTempDraft, kODNULL, 5, kODNSDataTypeODObject);
- }
-
- {
- char key[9];
- CreateISOStrKeyFromULong((ODULong)fDocument, key);
- ODDraft* unusedDraft;
- if (nameSpace->GetEntry(ev, key, (ODObject**)&unusedDraft))
- {
- WARN("There was a temp draft already in this namespace???");
- nameSpace->Unregister(ev, key);
- }
- nameSpace->Register(ev, key, fTempDraft);
- }
- }
-
- //------------------------------------------------------------------------------
- // ODOpenDocumentRef::RemoveFromTempDraftNS
- //
- // not currently needed because the last thing that ::Open does is to add to
- // temp draft NS. If that fails, then it doesn't need to be undone.
- //------------------------------------------------------------------------------
- #if 0
- void ODOpenDocumentRef::RemoveFromTempDraftNS(Environment* ev)
- {
- ODNameSpaceManager* fNameSpaceManager = fSession->GetNameSpaceManager(ev);
-
- ODObjectNameSpace* nameSpace =
- (ODObjectNameSpace*)fNameSpaceManager->HasNameSpace( ev,
- kODDocumentTempDraft);
- if (nameSpace)
- {
- char key[9];
- CreateISOStrKeyFromULong((ODULong)fDocument, key);
- ODDraft* unusedDraft;
- #if ODDebug
- if (!nameSpace->GetEntry(ev, key, (ODObject**)&unusedDraft))
- WARN("No temp draft to remove!");
- #endif
- nameSpace->RemoveEntry(ev, key, fTempDraft);
- }
- }
- #endif /* 0 */
-